package rxhttpext

import android.content.Context
import android.net.ConnectivityManager
import com.google.gson.JsonSyntaxException
import com.licheedev.context.AppProvider
import com.licheedev.rxhttpextdemo.R
import rxhttp.wrapper.exception.HttpStatusCodeException
import rxhttp.wrapper.exception.ParseException
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.net.UnknownHostException
import java.util.concurrent.TimeoutException

/**
 * 获取错误码，如果返回 [Int.MIN_VALUE]，表示该异常不含有错误码
 */
val Throwable.defaultHttpErrorCode: Int
    get() {
        val errorCode = when (this) {
            is HttpStatusCodeException -> {//请求失败异常
                this.statusCode
            }
            is ParseException -> {  // ParseException异常表明请求成功，但是数据不正确
                this.errorCode
            }
            else -> {
                ""
            }
        }
        return try {
            errorCode.toInt()
        } catch (e: Exception) {
            Int.MIN_VALUE
        }
    }

/**
 * 获取异常错误消息
 */
val Throwable.defaultHttpErrorMsg: String
    get() {
        var errorMsg = handleNetworkException(this)  //网络异常
        if (this is HttpStatusCodeException) {               //请求失败异常
            val code = this.statusCode
            if ("416" == code) {
                errorMsg = AppProvider.application.getString(R.string.request_range_illegal)
            }
        } else if (this is JsonSyntaxException) {  //请求成功，但Json语法异常,导致解析失败
            errorMsg = AppProvider.application.getString(R.string.parse_data_error)
        } else if (this is ParseException) {       // ParseException异常表明请求成功，但是数据不正确
            errorMsg = this.message ?: errorCode   //errorMsg为空，显示errorCode
        }
        return errorMsg ?: message ?: this.toString()
    }

//处理网络异常
private fun <T> handleNetworkException(throwable: T): String? {
    val stringId =
        if (throwable is UnknownHostException) { //网络异常
            if (!isNetworkConnected(AppProvider.application)) R.string.network_error else R.string.notify_no_network
        } else if (throwable is SocketTimeoutException || throwable is TimeoutException) {
            R.string.time_out_please_try_again_later  //前者是通过OkHttpClient设置的超时引发的异常，后者是对单个请求调用timeout方法引发的超时异常
        } else if (throwable is ConnectException) {
            R.string.esky_service_exception  //连接异常
        } else {
            -1
        }
    return if (stringId == -1) null else AppProvider.application.getString(stringId)
}

private fun isNetworkConnected(context: Context): Boolean {
    val mConnectivityManager =
        context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    val mNetworkInfo = mConnectivityManager.activeNetworkInfo
    if (mNetworkInfo != null) {
        return mNetworkInfo.isAvailable
    }
    return false
}
